package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

    @Autowired
    private TrackInfoMapper trackInfoMapper;

    @Autowired
    private TrackStatMapper trackStatMapper;

    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private VodService vodService;


    @Override
    public void saveTrackInfo(Long userId, TrackInfoVo trackInfoVo) {
        // trackInfo
        TrackInfo trackInfo = BeanUtil.copyProperties(trackInfoVo, TrackInfo.class);
        trackInfo.setUserId(userId);
        Integer maxOrderNum = trackInfoMapper.selectMaxOrderNumByAlbumId(trackInfoVo.getAlbumId());
        int newOrderNum = maxOrderNum == null ? 1 : maxOrderNum + 1;
        trackInfo.setOrderNum(newOrderNum);
        trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS);
        TrackMediaInfoVo trackMediaInfoVo = vodService.getMediaInfo(trackInfoVo.getMediaFileId());
        if (trackMediaInfoVo != null) {
            trackInfo.setMediaDuration(new BigDecimal(trackMediaInfoVo.getDuration()));
            trackInfo.setMediaSize(trackMediaInfoVo.getSize());
            trackInfo.setMediaType(trackMediaInfoVo.getType());
        }
        trackInfoMapper.insert(trackInfo);
        // albumInfo --> includeTrackCount
        AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
        albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount() + 1);
        albumInfoMapper.updateById(albumInfo);
        // trackStat
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PLAY, 10);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COLLECT, 20);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PRAISE, 30);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COMMENT, 40);

    }

    @Override
    public void saveTrackStat(Long trackId, String statType, Integer statNum) {
        TrackStat trackStat = new TrackStat();
        trackStat.setTrackId(trackId);
        trackStat.setStatType(statType);
        trackStat.setStatNum(statNum);
        trackStatMapper.insert(trackStat);
    }

    @Override
    public Page<TrackListVo> findUserTrackPage(Long page, Long limit, TrackInfoQuery trackInfoQuery) {
        Page<TrackListVo> trackListVoPage = new Page<>(page, limit);
        trackListVoPage = trackInfoMapper.findUserTrackPage(trackListVoPage, trackInfoQuery);
        return trackListVoPage;
    }

    @Override
    public void saveTrackInfoById(Long userId, Long id, TrackInfoVo trackInfoVo) {
        // 判断是否为新音频文件
        String mediaFileId = trackInfoVo.getMediaFileId();
        log.info("新mediaFileId:" + mediaFileId);
        TrackInfo trackInfo = trackInfoMapper.selectById(id);
        log.info("旧mediaFileId:" + trackInfo.getMediaFileId());
        if (!mediaFileId.equals(trackInfo.getMediaFileId())) {
            // 删除旧音频文件
            vodService.deleteMedia(trackInfo.getMediaFileId());
        }
        // trackInfo

        TrackInfo trackInfoNew = BeanUtil.copyProperties(trackInfoVo, TrackInfo.class);
        trackInfoNew.setId(id);
        trackInfoNew.setUserId(userId);
        trackInfoNew.setSource(SystemConstant.TRACK_SOURCE_USER);
        TrackMediaInfoVo mediaInfo = vodService.getMediaInfo(mediaFileId);
        if (mediaInfo != null) {
            trackInfoNew.setMediaDuration(new BigDecimal(mediaInfo.getDuration()));
            trackInfoNew.setMediaSize(mediaInfo.getSize());
            trackInfoNew.setMediaType(mediaInfo.getType());
        }

        trackInfoMapper.updateById(trackInfoNew);

    }

    @Override
    public void removeTrackInfoById(Long id) {
        // 1. 查询要删除的声音信息
        TrackInfo trackInfo = trackInfoMapper.selectById(id);
        if (trackInfo == null) {
            return; // 如果记录不存在，直接返回
        }

        Long albumId = trackInfo.getAlbumId();
        Integer deletedOrderNum = trackInfo.getOrderNum();
        String mediaFileId = trackInfo.getMediaFileId();

        // 2. 重新排序同专辑下剩余声音的orderNum（在删除前进行）
        if (albumId != null && deletedOrderNum != null) {
            LambdaQueryWrapper<TrackInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(TrackInfo::getAlbumId, albumId);
            wrapper.gt(TrackInfo::getOrderNum, deletedOrderNum);
            List<TrackInfo> trackInfos = trackInfoMapper.selectList(wrapper);

            if (!CollectionUtils.isEmpty(trackInfos)) {
                for (TrackInfo info : trackInfos) {
                    info.setOrderNum(info.getOrderNum() - 1);
                    trackInfoMapper.updateById(info);
                }
            }
        }

        // 3. 删除track_info表中的记录
        trackInfoMapper.deleteById(id);

        // 4. 删除track_stat表中的相关统计信息
        trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId, id));

        // 5. 更新album_info中的include_track_count字段
        if (albumId != null) {
            LambdaUpdateWrapper<AlbumInfo> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(AlbumInfo::getId, albumId);
            updateWrapper.setSql("include_track_count = include_track_count - 1");
            albumInfoMapper.update(null, updateWrapper);
        }

        // 6. 最后删除vod端的声音文件（如果前面步骤都成功）
        if (mediaFileId != null) {
            try {
                vodService.deleteMedia(mediaFileId);
            } catch (Exception e) {
                log.error("删除vod媒体文件失败，mediaFileId: {}", mediaFileId, e);
                // 可以选择是否抛出异常回滚整个事务
            }
        }

    }

    /**
     * 0101 免费
     * 0102 vip免费（只有vip才能查看，且vip也需要购买） -- vip和普通用户购买折扣不同
     * 0103 完全付费（只有完全付费的才能查看） --vip和普通用户购买折扣不同
     * @param albumId
     * @param trackListVoPage
     * @param userId
     * @return
     */
    @Override
    public Page<AlbumTrackListVo> findAlbumTrackPage(Long albumId, Page<AlbumTrackListVo> trackListVoPage, Long userId) {
        Page<AlbumTrackListVo> albumTrackPage = trackInfoMapper.findAlbumTrackPage(albumId, trackListVoPage);
        List<AlbumTrackListVo> records = albumTrackPage.getRecords();
        // 专辑信息
        LambdaQueryWrapper<AlbumInfo> albumInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        albumInfoLambdaQueryWrapper.eq(AlbumInfo::getId, albumId);
        AlbumInfo albumInfo = albumInfoMapper.selectOne(albumInfoLambdaQueryWrapper);
        Assert.notNull(albumInfo, "专辑不存在", albumId);
        String payType = albumInfo.getPayType();
        // 专辑免费的情况不论用户是否登录均不做处理
        if (SystemConstant.ALBUM_PAY_TYPE_FREE.equals(payType)){
            return albumTrackPage;
        }
        // 1.判断是否为登录状态
        // 1.1 未登录状态 -- 判断专辑 album(pay_type 付费类型: 0101-免费、0102-vip免费、0103-付费 tracks_for_free 免费试听集数)
        if (userId == null) {
            // 未登录即除了免费的专辑，其他的应该均显示付费标识
            if (payType.equals(SystemConstant.ALBUM_PAY_TYPE_VIPFREE) || payType.equals(SystemConstant.ALBUM_PAY_TYPE_REQUIRE)) {
//                List<AlbumTrackListVo> newRecords = new ArrayList<>();
//                for (AlbumTrackListVo record : records) {
//                    // 免费试听集数
//                    Integer tracksForFree = albumInfo.getTracksForFree();
//                    // 排序规则
//                    Integer orderNum = record.getOrderNum();
//                    if (tracksForFree >= orderNum) {
//                        // 免费
//                        record.setIsShowPaidMark(false);
//                    } else {
//                        // 付费
//                        record.setIsShowPaidMark(true);
//                    }
//                    newRecords.add(record);
//                }
//                albumTrackPage.setRecords(newRecords);
                List<AlbumTrackListVo> newRecords = new ArrayList<>();
                for (AlbumTrackListVo record : records) {
                    record.setIsShowPaidMark(true);
                    newRecords.add(record);
                }

                albumTrackPage.setRecords(newRecords);

                return albumTrackPage;
            }
        }else {
            // 1.2 登录状态 -- 判断专辑 album(pay_type 付费类型: 0101-免费、0102-vip免费、0103-付费 tracks_for_free 免费试听集数)
            // 1.2.1 登录状态判断用户是否是 vip ,以及 vip 是否到期 需要远程调用 userClient 服务
            UserInfoVo userInfoVo = userFeignClient.getUserInfoVo(userId).getData();
            Integer tracksForFree = albumInfo.getTracksForFree();
            Integer isVip = userInfoVo.getIsVip();
            List<Long> checkTrackIds = new ArrayList<>();
            // 过滤掉免费试听的声音 排序编号 > 免费试听集数 待判断声音是否购买留下
            List<AlbumTrackListVo> checkList = records.stream().filter(record -> record.getOrderNum() > tracksForFree).collect(Collectors.toList());
            if (checkList.size() > 0) {
                // 需要拿到待检查的 trackIds
                checkTrackIds = checkList.stream().map(AlbumTrackListVo::getTrackId).collect(Collectors.toList());
            }

            // 不是会员
            if(isVip.intValue() == 0 || (new Date().after(userInfoVo.getVipExpireTime()))){
                // 非会员 但是需要判断之前是否直接购买过专辑或者声音
                // 调用 userFeignClient
                Map<Long, Integer> checkedTrackMap = userFeignClient.userIsPaidTrack(userId, albumId, checkTrackIds).getData();

                List<AlbumTrackListVo> newRecords = new ArrayList<>();
                for (AlbumTrackListVo record : records) {
                    // 排序规则
                    Integer orderNum = record.getOrderNum();
                    if (tracksForFree >= orderNum) {
                        // 免费
                        record.setIsShowPaidMark(false);
                    } else {
                        // 根据 checkedTrackMap 填充 isShowPaidMark 应为此时都是免费试听集数过后的待判断的声音列表
                        // 超出免费试听集数的声音，需要根据购买状态判断
                        // 从checkedTrackMap中获取该声音的购买状态，如果未找到默认为0(未购买)
                        Integer isPaid = checkedTrackMap.getOrDefault(record.getTrackId(), 0);
                        // 0表示未购买需要付费，1表示已购买不需要付费
                        record.setIsShowPaidMark(isPaid == 0);
                    }
                    newRecords.add(record);
                }
                albumTrackPage.setRecords(newRecords);
                return albumTrackPage;
            }else if (isVip.intValue() == 1){
                // 会员

                if(payType.equals(SystemConstant.ALBUM_PAY_TYPE_VIPFREE)){
                    // vip免费 -- 不做处理
                    return albumTrackPage;
                }else if (payType.equals(SystemConstant.ALBUM_PAY_TYPE_REQUIRE)){
                    // 完全付费 -- 即使是vip也要做处理
                    Map<Long, Integer> checkedTrackMap = userFeignClient.userIsPaidTrack(userId, albumId, checkTrackIds).getData();
                    List<AlbumTrackListVo> newRecords = new ArrayList<>();
                    for (AlbumTrackListVo record : records) {
                        // 排序规则
                        Integer orderNum = record.getOrderNum();
                        if (tracksForFree >= orderNum) {
                            // 免费
                            record.setIsShowPaidMark(false);
                        } else {
                            // 根据 checkedTrackMap 填充 isShowPaidMark 应为此时都是免费试听集数过后的待判断的声音列表
                            // 超出免费试听集数的声音，需要根据购买状态判断
                            // 从checkedTrackMap中获取该声音的购买状态，如果未找到默认为0(未购买)
                            Integer isPaid = checkedTrackMap.getOrDefault(record.getTrackId(), 0);
                            // 0表示未购买需要付费，1表示已购买不需要付费
                            record.setIsShowPaidMark(isPaid == 0);
                        }
                        newRecords.add(record);
                    }
                    albumTrackPage.setRecords(newRecords);
                    return albumTrackPage;
                }
            }

        }
        return null;

    }

    @Override
    public TrackStatVo getTrackStatVo(Long trackId) {
        TrackStatVo trackStatVo = trackStatMapper.getTrackStatVo(trackId);
        return trackStatVo;
    }


}
